home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Extensions / Imaging / PIL / ImageFont.py < prev    next >
Encoding:
Text File  |  2000-06-23  |  2.8 KB  |  118 lines

  1. #
  2. # THIS IS WORK IN PROGRESS.
  3. #
  4. # The Python Imaging Library.
  5. # $Id: ImageFont.py,v 1.1.1.2 1999/01/13 09:40:06 sjoerd Exp $
  6. #
  7. # PIL raster font management
  8. #
  9. # History:
  10. # 96-08-07 fl    Created (experimental)
  11. # 97-08-25 fl    Minor adjustments to handle fonts from pilfont 0.3
  12. #
  13. # Todo:
  14. # Adapt to PILFONT2 format (16-bit fonts, compressed, single file)
  15. #
  16. # Copyright (c) Secret Labs AB 1997-98.
  17. # Copyright (c) Fredrik Lundh 1996-97.
  18. #
  19. # See the README file for information on usage and redistribution.
  20. #
  21.  
  22. import Image
  23. import math, os, string, sys
  24.  
  25. # --------------------------------------------------------------------
  26. # Font metrics format:
  27. #    "PILfont" LF
  28. #    fontdescriptor LF
  29. #    (optional) key=value... LF
  30. #    "DATA" LF
  31. #    binary data: 256*10*2 bytes (dx, dy, dstbox, srcbox)
  32. #
  33. # To place a character, cut out srcbox and paste at dstbox,
  34. # relative to the character position.  Then move the character
  35. # position according to dx, dy.
  36. # --------------------------------------------------------------------
  37.  
  38. def i16(c):
  39.     v = (ord(c[0])<<8) + ord(c[1])
  40.     if v >= 32768:
  41.     v = v - 65536
  42.     return v
  43.  
  44. class ImageFont:
  45.  
  46.     def _load_pilfont(self, filename):
  47.  
  48.     fp = open(filename, "rb")
  49.  
  50.     # read PILfont header
  51.     if fp.readline() != "PILfont\n":
  52.         raise SyntaxError, "Not a PILfont file"
  53.     d = string.split(fp.readline(), ";")
  54.     self.props = [] # FIXME: should be a dictionary
  55.     s = fp.readline()
  56.     while s and s != "DATA\n":
  57.         self.props.append(s)
  58.  
  59.     # read PILfont metrics
  60.     self.metrics = []
  61.         y0 = y1 = 0
  62.     for i in range(256):
  63.         s = fp.read(20)
  64.         if len(s) != 20:
  65.         raise SyntaxError, "Broken PILfont file"
  66.         m = map(lambda a,s=s: i16(s[a:a+2]), range(0,20,2))
  67.             y0 = min(y0, m[3])
  68.             y1 = max(y1, m[5])
  69.         self.metrics.append(m)
  70.  
  71.         self.baseline = -y0
  72.         self.ysize = y1-y0
  73.  
  74.     try:
  75.         self.image = Image.open(os.path.splitext(filename)[0] + ".gif")
  76.     except:
  77.         self.image = Image.open(os.path.splitext(filename)[0] + ".pbm")
  78.  
  79.     self.image.load()
  80.  
  81.     def getsize(self, str):
  82.     w = 0
  83.     for id in map(ord, str):
  84.         w = w + self.metrics[id][0]
  85.     if w == 0:
  86.         return 0, 0
  87.     return w, self.ysize
  88.  
  89.     def getmask(self, str):
  90.     # FIXME: this should be reimplemented in C
  91.     im = Image.new("1", self.getsize(str), 0)
  92.     x = 0
  93.         b = self.baseline
  94.     for m in map(lambda c, m=self.metrics: m[ord(c)], str):
  95.         [x0, y0, x1, y1] = m[2:6]
  96.         im.paste(self.image.crop(tuple(m[6:10])), (x0+x, y0+b, x1+x, y1+b))
  97.         x = x + m[0]
  98.     return im
  99.  
  100. #
  101. # --------------------------------------------------------------------
  102.  
  103. def load(filename):
  104.     "Load a font file."
  105.     f = ImageFont()
  106.     f._load_pilfont(filename)
  107.     return f
  108.  
  109. def load_path(filename):
  110.     "Load a font file, searching along the Python path."
  111.     for dir in sys.path:
  112.     try:
  113.         return load(os.path.join(dir, filename))
  114.     except:
  115.         pass
  116.     raise IOError, "cannot find font file"
  117.  
  118.